/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entrada;

import atualizaestoque.RepositorioAtualizaEstoque;
import com.sun.jmx.trace.Trace;
import compra.Compra;
import detalhamentoEntrada.DetalhamentoEntrada;
import entrada.Entrada;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import produto.Produto;
import statusProduto.StatusProduto;
import util.ErroAcessoRepositorioException;
import util.HibernateUtil;

/**
 *
 * @author Alberto
 */
public class RepositorioEntrada {
    
    
    public RepositorioEntrada(){}
    
    /**
     * Método que ira cadastrar a entrada de materiais na base
     * 
     * @param objEntrada
     * @return int idEntrada
     * @throws Exception 
     */
    public int inserirEntrada(Entrada objEntrada) throws Exception{
        int idEntrada = 0;
        Session s = null;
        Transaction t = null;
        try {
            // recuperando a instência de banco
            s = HibernateUtil.getSessionFactory().getCurrentSession();
            // abrindo uma transação
            t  = s.beginTransaction();
            // Sanvando a entrada
            s.saveOrUpdate(objEntrada);
            // Recurepando o id salvo
            idEntrada = objEntrada.getIdEntrada();
            StatusProduto objStatusProduto = (StatusProduto) s.get(StatusProduto.class, 1);
            RepositorioAtualizaEstoque objAtualizaEstoque = new RepositorioAtualizaEstoque();
            
            for (DetalhamentoEntrada objDetalhamentoEntrada : objEntrada.getDetalhamentoEntradas()){
                // setando o Id da entrada
                objDetalhamentoEntrada.setEntrada(objEntrada);
                
                // Salvando o detalhamento entrada na base
                s.saveOrUpdate(objDetalhamentoEntrada);
                
                // Recuperando a compra
                Compra objCompra = objDetalhamentoEntrada.getCompra();
                
                // Setando o status da compra para recebido
                objCompra.setFlagRecebido(true);
                
                // Atualizando a compra na base
                s.saveOrUpdate(objCompra);
                
                // realizando uma interação Para cadatsrar todos os produtos que foram dado entrada
                for(int qtdProduto = 0 ; qtdProduto < objDetalhamentoEntrada.getQtdProduto() ; qtdProduto ++){
                    // (int idProduto, Fornecedor fornecedor, DescricaoProduto descricaoProduto, Date dataEntrada,
                    //Date dataValidade, Double valorUnitario, String notaProduto, String numeroSerie, Double precoCusto, 
                    //Double precoRevenda, String narrativaProduto, StatusProduto statusProduto) 
                    Produto objProduto = new Produto(0, objEntrada.getFornecedor(), objDetalhamentoEntrada.getDescricaoProduto(),
                            objEntrada.getDataEntrada(), null, objDetalhamentoEntrada.getValorUnidade(), null, null, 00.00, 00.00, 
                            "Produto em estoque", objStatusProduto);
                    
                    // Setando o detalhamento entrada
                    objProduto.setDetalhamentoEntrada(objDetalhamentoEntrada);
                    
                    // Salvando o produto na base
                    s.save(objProduto);
                }
                
                // ATUALIZANDO O ESTOQUE 
                objAtualizaEstoque.atualizarEstoqueentrada(s, t, objDetalhamentoEntrada);
            }
            // Comitando toda as operações realizadas
            t.commit();
            
        } catch (Exception e) {
            e.printStackTrace();
            t.rollback();
            throw new ErroAcessoRepositorioException(e.getMessage(), null, 1);
        }
        return idEntrada;
    }
    
    /**
     * Método que ira cancelar a entrada de materiais na base
     * 
     * @param objEntrada
     * @return int idEntrada
     * @throws Exception 
     */
    public int cancelarEntrada(Entrada objEntrada) throws Exception{
        int idEntrada = 0;
        Session s = null;
        Transaction t = null;
        try {
            // recuperando a instência de banco
            s = HibernateUtil.getSessionFactory().getCurrentSession();
            // abrindo uma transação
            t  = s.beginTransaction();
            
            RepositorioAtualizaEstoque objAtualizaEstoque = new RepositorioAtualizaEstoque();
            
            
            for (DetalhamentoEntrada objDetalhamentoEntrada : objEntrada.getDetalhamentoEntradas()){
                
                // ATUALIZANDO O ESTOQUE 
                objAtualizaEstoque.atualizarEstoqueCancelamentoEntrada(s, t, objDetalhamentoEntrada);
                
                // Recuperando a compra
                Compra objCompra = objDetalhamentoEntrada.getCompra();
                
                // Setando o status da compra para não recebido
                objCompra.setFlagRecebido(false);
                
                // Atualizando a compra na base
                s.saveOrUpdate(objCompra);
                
                // excluindo os produtos na base
                Query q = s.createSQLQuery("DELETE FROM produto WHERE id_detalhamento_entrada = :id_detalhamento_entrada");
                
                q.setParameter("id_detalhamento_entrada", objDetalhamentoEntrada.getIdDetalhamanetoEntrada());
                
                q.executeUpdate();
                
                // Salvando o detalhamento entrada na base
                s.saveOrUpdate(objDetalhamentoEntrada);
                
            }
            
            // Sanvando a entrada
            s.delete(objEntrada);
            
            // Comitando toda as operações realizadas
            t.commit();
            
        } catch (Exception e) {
            e.printStackTrace();
            t.rollback();
            throw new ErroAcessoRepositorioException(e.getMessage(), null, 1);
        }
        return idEntrada;
    }
    
    /**
     * Método que ira buscar a entrada na base pelo seu Identificador
     * 
     * @param idEntrada
     * @return Entrada
     * @throws Exception 
     */
    public Entrada procurarEntrada(int idEntrada)throws Exception{
        Entrada objEntrada = null;
        // Iniciando as sessões 
        Session s = null;
        Transaction t = null;
        try {
            s = HibernateUtil.getSessionFactory().getCurrentSession();
            t = s.beginTransaction();
            // Salvando o produto no banco
            objEntrada = (Entrada) s.get(Entrada.class, idEntrada);
            // Comtando tudo caso der certo
            t.commit();
        } catch (Exception e) {
            t.rollback();
            throw new Exception(e.getMessage());
        }
        
        return objEntrada;
    }
    
    
    /**
     * List<Entrada>
     * 
     * @return 
     */
    public List<Entrada> listarEntradas() throws Exception{
        // List que contera os objetos Entrada
        List<Entrada> listEntrada = new ArrayList<Entrada>();
        
        // Iniciando as sessões 
        Session s = null;
        Transaction t = null;
        try {
            // recuperando a instência de banco
            s = HibernateUtil.getSessionFactory().getCurrentSession();
            // abrindo uma transação
            t  = s.beginTransaction();
            
            // Criando a query 
            Query q = s.createQuery("from Entrada  WHERE id_entrada IS NOT NULL ORDER BY id_entrada desc, id_fornecedor desc,data_entrada desc");
            
            // Listando as entrada da bases
            listEntrada = q.list();
            
            // Comintando a transação
            t.commit();
            
        } catch (Exception e) {
            t.rollback();
            // Lançando a exceção
            throw new Exception(e.getMessage());
        }
        
        return listEntrada;
    }
    
    
    /**
     * Metodo que ira listar os Categorias
     *
     * @return Collection
     */
    public List<Entrada> listarPorFornecedorPorFuncionarioPorData(int idFornecedor, int idFuncionario, Date dataInicial, Date dataFinal) throws Exception, ErroAcessoRepositorioException {
        List<Entrada> listEntrada = null;
        Session s = null;
        Transaction t = null;
        try {
            s = HibernateUtil.getSessionFactory().getCurrentSession();
            t = s.beginTransaction();
            // criando o sql
            String sql = "from Entrada  WHERE id_entrada IS NOT NULL ";
            
            if(idFornecedor > 0){
                sql += " AND id_fornecedor = :id_fornecedor ";
            }
            if(idFuncionario > 0){
                sql += " AND id_funcionario = :id_funcionario ";
            }
            
            if(dataInicial.toString().trim().length() > 0 && dataFinal.toString().trim().length() > 0)
                sql += " AND data_entrada between :data_entrada_inicial AND :data_entrada_final ";
            
            // Criando a query
            Query q = s.createQuery(sql + " ORDER BY id_entrada DESC, data_entrada DESC");
            if(idFornecedor > 0){
                q.setParameter("id_fornecedor", idFornecedor);
            }
            if(idFuncionario > 0){
                q.setParameter("id_funcionario", idFuncionario);
            }
            
            if(dataInicial.toString().trim().length() > 0)
                q.setParameter("data_entrada_inicial", dataInicial);
            
            if(dataFinal.toString().trim().length() > 0)
                q.setParameter("data_entrada_final", dataFinal);
            
            
            // Listando as categorias
            listEntrada = q.list();
            
            t.commit();
            
        } catch (Exception e) {
            t.rollback();
            throw new ErroAcessoRepositorioException(e.getMessage(), null, 1);
        }
        return listEntrada;
    }
    
}